package com.ticket.sass.provider.business.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ticket.sass.common.entity.tenant.FilmEntity;
import com.ticket.sass.common.entity.tenant.FilmVersionEntity;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import com.ticket.sass.provider.business.FilmBusiness;
import com.ticket.sass.provider.dto.film.FilmListOutput;
import com.ticket.sass.provider.dto.film.FilmVersionOutput;
import com.ticket.sass.provider.dto.input.film.FilmAddInput;
import com.ticket.sass.provider.dto.input.film.FilmListInput;
import com.ticket.sass.provider.dto.input.film.FilmUpdInput;
import com.ticket.sass.provider.dto.input.film.FilmVersionInput;
import com.ticket.sass.provider.service.PageModel;
import com.ticket.sass.provider.service.impl.FilmServiceImpl;
import com.ticket.sass.provider.service.impl.FilmVersionServiceImpl;
import com.ticket.sass.provider.util.EscapeUtil;
import com.ticket.sass.provider.util.ModelUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.TypeToken;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2024-03-28 17:01
 */
@Slf4j
@Service
@AllArgsConstructor
public class FilmBusinessImpl implements FilmBusiness {
    
    final ModelUtil modelUtil;
    final FilmServiceImpl filmService;
    final FilmVersionServiceImpl filmVersionService;
    
    @Override
    public PageModel<FilmListOutput> list(FilmListInput input) {
        IPage<FilmEntity> filmEntityIPage = filmService.iPage(input);
        
        // 转换影片列表对象为输出对象
        List<FilmListOutput> outputs = modelUtil.listToList(filmEntityIPage.getRecords(), new TypeToken<List<FilmListOutput>>(){}.getType());
        
        Map<Long, List<FilmVersionOutput>> filmVersionsByFilmIds = filmVersionService.getFilmVersionsByFilmIds(outputs.stream().map(FilmListOutput::getId).collect(Collectors.toList()));
        
        outputs.forEach(o -> o.setVersions(filmVersionsByFilmIds.get(o.getId())));
        
        
        // 返回分页模型对象，假设总记录数为影片列表的大小
        return new PageModel<>(filmEntityIPage.getTotal(), outputs);
    }
    
    @Override
    public void add(FilmAddInput input) {
        FilmEntity filmEntity = convertFromInput(input);
        // 将输入对象转换为影片实体对象并保存
        filmService.save(filmEntity);
        
        if (input.getVersions().size() > 0){
            List<String> codeList = input.getVersions().stream().map(FilmVersionInput::getCode).collect(Collectors.toList());
            if (!filmVersionService.areCodeListNotExist(codeList)) {
                throw new BadRequestException(
                    ErrorCode.RECORD_EXIST,
                    EscapeUtil.errorMessage("version", "版本编码已存在！")
                );
            }
            List<FilmVersionEntity> collect = input.getVersions().stream()
                .map(version -> new FilmVersionEntity(version.getName(), version.getCode(), filmEntity.getId()))
                .collect(Collectors.toList());
            
            filmVersionService.saveBatch(collect);
        }
    }
    
    @Override
    public void upd(FilmUpdInput input) {
        // 将输入对象转换为影片实体对象并更新
        FilmEntity filmEntity = convertFromInput(input);
        
        filmService.updateById(filmEntity);
        
        // 获取当前数据库中的发行版本数据
        List<FilmVersionEntity> existingReleaseVersions = filmVersionService.getByMovieId(filmEntity.getId());
        
        // 判断是否有修改，新增或删除的操作
        List<FilmVersionEntity> additions = new ArrayList<>();
        List<FilmVersionEntity> modifications = new ArrayList<>();
        
        for (FilmVersionInput releaseInput : input.getVersions()) {
            FilmVersionEntity existingRelease = existingReleaseVersions.stream()
                .filter(e -> e.getCode().equals(releaseInput.getCode()))
                .findFirst()
                .orElse(null);
            
            if (existingRelease == null) {
                // 新增数据
                additions.add(new FilmVersionEntity(releaseInput.getName(), releaseInput.getCode(), filmEntity.getId()));
            } else if (!existingRelease.getName().equals(releaseInput.getName())) {
                // 修改数据
                existingRelease.setName(releaseInput.getName());
                modifications.add(existingRelease);
            }
        }
        
        // 找出需要删除的数据
        List<FilmVersionEntity> deletions = existingReleaseVersions.stream()
            .filter(e -> input.getVersions().stream().noneMatch(i -> i.getCode().equals(e.getCode()))).collect(Collectors.toList());
        
        // 执行删除操作
        if (!deletions.isEmpty()) {
            filmVersionService.removeByIds(deletions.stream().map(FilmVersionEntity::getId).collect(Collectors.toList()));
        }
        
        // 执行新增操作
        if (!additions.isEmpty()) {
            filmVersionService.saveBatch(additions);
        }
        
        // 执行修改操作
        if (!modifications.isEmpty()) {
            filmVersionService.updateBatchById(modifications);
        }
    }
    
    public static FilmEntity convertFromInput(FilmAddInput input) {
        FilmEntity film = new FilmEntity();
        film.setName(input.getName());
        film.setCover(input.getCover());
        film.setReleaseDate(input.getReleaseDate());
        film.setReleaseArea(input.getReleaseArea());
        film.setDirector(input.getDirector());
        if (Objects.nonNull(input.getActors())){
            film.setActor(String.join(",", input.getActors()));
        }
        if (Objects.nonNull(input.getTypes())){
            film.setType(String.join(",", input.getTypes()));
        }
        
        film.setDuration(input.getDuration());
        film.setDesc(input.getDesc());
        film.setScore(input.getScore());
        // 其他属性...
        
        return film;
    }
    
    public static FilmEntity convertFromInput(FilmUpdInput input) {
        FilmEntity film = new FilmEntity();
        film.setId(input.getId());
        film.setName(input.getName());
        film.setCover(input.getCover());
        film.setReleaseDate(input.getReleaseDate());
        film.setReleaseArea(input.getReleaseArea());
        film.setDirector(input.getDirector());
        if (Objects.nonNull(input.getActors())){
            film.setActor(String.join(",", input.getActors()));
        }
        if (Objects.nonNull(input.getTypes())){
            film.setType(String.join(",", input.getTypes()));
        }
        film.setDuration(input.getDuration());
        film.setDesc(input.getDesc());
        film.setScore(input.getScore());
        // 其他属性...
        
        return film;
    }
}
